<template>
  <a-modal
    class="image-out-painting"
    v-model:visible="visible"
    title="AI 扩图"
    :footer="false"
    @cancel="closeModal"
    width="800px"
  >
    <a-row gutter="16">
      <a-col span="12">
        <h4>原始图片</h4>
        <div class="image-container">
          <img :src="picture?.url" :alt="picture?.name" style="max-width: 100%" />
          <div class="image-info">
            <a-tag color="blue">{{ picture?.name }}</a-tag>
            <br>
            <small v-if="picture?.picWidth && picture?.picHeight">
              尺寸: {{ picture.picWidth }} × {{ picture.picHeight }}
            </small>
          </div>
        </div>
      </a-col>
      <a-col span="12">
        <h4>扩图结果</h4>
        <div class="result-container">
          <div v-if="taskStatus === 'RUNNING'" class="loading-container">
            <a-spin size="large" />
            <p>正在生成扩图，请耐心等待...</p>
            <a-progress
              :percent="progressPercent"
              :show-info="false"
              stroke-color="#1890ff"
            />
          </div>
          <div v-else-if="taskStatus === 'FAILED'" class="error-container">
            <a-result
              status="error"
              title="扩图失败"
              :sub-title="failureReason"
            >
              <template #extra>
                <a-button type="primary" @click="retryTask">重试</a-button>
              </template>
            </a-result>
          </div>
          <img
            v-else-if="resultImageUrl"
            :src="resultImageUrl"
            :alt="picture?.name"
            style="max-width: 100%"
          />
          <div v-else class="placeholder-container">
            <a-empty description="点击生成图片开始扩图" />
          </div>
        </div>
      </a-col>
    </a-row>

    <!-- 任务状态信息 -->
    <div v-if="taskId" class="task-info">
      <a-alert
        :type="getAlertType()"
        :message="getStatusMessage()"
        :description="getStatusDescription()"
        show-icon
        style="margin: 16px 0"
      />
    </div>

    <div style="margin-bottom: 16px" />
    <a-flex gap="16" justify="center">
      <a-button
        type="primary"
        :loading="taskStatus === 'RUNNING'"
        :disabled="!picture?.id"
        ghost
        @click="createTask"
      >
        {{ taskStatus === 'RUNNING' ? '生成中...' : '生成图片' }}
      </a-button>
      <a-button
        type="primary"
        v-if="resultImageUrl"
        :loading="uploadLoading"
        @click="handleUpload"
      >
        应用结果
      </a-button>
      <a-button v-if="taskId && taskStatus === 'RUNNING'" @click="cancelTask">
        取消任务
      </a-button>
    </a-flex>
  </a-modal>
</template>

<script setup lang="ts">
import { onUnmounted, ref, computed } from 'vue'
import {
  createPictureOutPaintingTaskUsingPost,
  getPictureOutPaintingTaskUsingGet,
  uploadPictureByUrlUsingPost,
} from '@/api/pictureController'
import { message } from 'ant-design-vue'

interface Props {
  picture?: API.PictureVO
  spaceId?: number
  onSuccess?: (newPicture: API.PictureVO) => void
}

const props = defineProps<Props>()

// 错误代码映射表
const ERROR_CODE_MAP = {
  'InvalidParameter.ImageResolution': {
    title: '图片分辨率不符合要求',
    description: '请使用分辨率在 64×64 到 4096×4096 像素之间的图片。当前图片可能过小或过大。',
    suggestion: '建议调整图片尺寸后重试'
  },
  'InvalidParameter.ImageFormat': {
    title: '图片格式不支持',
    description: '请使用 JPG、PNG 或 WebP 格式的图片',
    suggestion: '请转换图片格式后重试'
  },
  'InvalidParameter.ImageSize': {
    title: '图片文件过大',
    description: '图片文件大小超出限制',
    suggestion: '请压缩图片后重试'
  },
  'InsufficientBalance': {
    title: '账户余额不足',
    description: '当前账户余额不足以完成此操作',
    suggestion: '请充值后重试'
  },
  'RateLimitExceeded': {
    title: '请求过于频繁',
    description: '您的请求过于频繁，已被系统限制',
    suggestion: '请稍后再试'
  }
}

// 是否可见
const visible = ref(false)
// 任务状态
const taskStatus = ref<string>('')
// 失败原因
const failureReason = ref<string>('')
// 结果图片URL
const resultImageUrl = ref<string>()
// 任务ID
const taskId = ref<string>()
// 上传加载状态
const uploadLoading = ref<boolean>(false)
// 进度百分比
const progressPercent = ref(0)
// 轮询计数器（用于模拟进度）
let pollingCount = 0

// 打开弹窗
const openModal = () => {
  visible.value = true
  // 重置状态
  resetState()
}

// 关闭弹窗
const closeModal = () => {
  visible.value = false
  clearPolling()
  resetState()
}

// 重置状态
const resetState = () => {
  taskStatus.value = ''
  failureReason.value = ''
  resultImageUrl.value = ''
  taskId.value = ''
  progressPercent.value = 0
  pollingCount = 0
}

// 获取警告类型
const getAlertType = () => {
  switch (taskStatus.value) {
    case 'RUNNING': return 'info'
    case 'SUCCEEDED': return 'success'
    case 'FAILED': return 'error'
    default: return 'info'
  }
}

// 获取状态消息
const getStatusMessage = () => {
  switch (taskStatus.value) {
    case 'RUNNING': return '任务执行中'
    case 'SUCCEEDED': return '扩图成功'
    case 'FAILED': return '扩图失败'
    default: return '准备就绪'
  }
}

// 获取状态描述
const getStatusDescription = () => {
  switch (taskStatus.value) {
    case 'RUNNING': return `任务ID: ${taskId.value} | 预计耗时: 30-60秒`
    case 'SUCCEEDED': return '图片扩图完成，您可以预览结果并选择应用'
    case 'FAILED': return failureReason.value
    default: return ''
  }
}

/**
 * 创建任务
 */
const createTask = async () => {
  if (!props.picture?.id) {
    message.warning('未选择图片')
    return
  }

  try {
    // 检查图片尺寸（如果有的话）
    if (props.picture.picWidth && props.picture.picHeight) {
      const { picWidth, picHeight } = props.picture
      if (picWidth < 64 || picHeight < 64) {
        message.error('图片分辨率过小，最小支持 64×64 像素')
        return
      }
      if (picWidth > 4096 || picHeight > 4096) {
        message.error('图片分辨率过大，最大支持 4096×4096 像素')
        return
      }
    }

    taskStatus.value = 'RUNNING'
    progressPercent.value = 10

    const res = await createPictureOutPaintingTaskUsingPost({
      pictureId: props.picture.id,
      parameters: {
        xScale: 2,
        yScale: 2,
      },
    })

    if (res.data.code !== 0) {
      throw new Error(res.data.message || 'API调用失败')
    }

    if (!res.data.data || !res.data.data.output) {
      throw new Error('返回数据格式错误')
    }

    const output = res.data.data.output
    const { taskStatus: status, taskId: id, code: errorCode, message: errorMessage } = output

    // 处理不同的任务状态
    if (status === 'FAILED') {
      taskStatus.value = 'FAILED'
      const errorInfo = ERROR_CODE_MAP[errorCode]
      if (errorInfo) {
        failureReason.value = `${errorInfo.title}: ${errorInfo.description}。${errorInfo.suggestion}`
      } else {
        failureReason.value = errorMessage || '任务执行失败，请重试'
      }
      message.error(`创建任务失败: ${errorInfo?.title || errorMessage}`)
      return
    }

    // 任务创建成功
    taskId.value = id
    message.success('创建任务成功，正在生成扩图...')
    console.log('Task created successfully:', id)

    // 开启轮询
    startPolling()

  } catch (error) {
    taskStatus.value = 'FAILED'
    failureReason.value = error.message || '网络错误，请重试'
    message.error(`创建任务失败: ${error.message}`)
    console.error('Create task error:', error)
  }
}

// 轮询定时器
let pollingTimer: NodeJS.Timeout | null = null

// 清理轮询定时器
const clearPolling = () => {
  if (pollingTimer) {
    clearInterval(pollingTimer)
    pollingTimer = null
  }
}

// 开始轮询
const startPolling = () => {
  if (!taskId.value) return

  pollingCount = 0
  pollingTimer = setInterval(async () => {
    try {
      pollingCount++
      // 模拟进度增长
      if (progressPercent.value < 90) {
        progressPercent.value += Math.random() * 10
      }

      const res = await getPictureOutPaintingTaskUsingGet({
        taskId: taskId.value,
      })

      if (res.data.code !== 0) {
        throw new Error(res.data.message || '查询任务状态失败')
      }

      if (!res.data.data || !res.data.data.output) {
        throw new Error('任务状态数据格式错误')
      }

      const taskResult = res.data.data.output
      console.log('Polling result:', taskResult)

      if (taskResult.taskStatus === 'SUCCEEDED') {
        taskStatus.value = 'SUCCEEDED'
        progressPercent.value = 100
        resultImageUrl.value = taskResult.outputImageUrl
        message.success('扩图任务完成！')
        clearPolling()
      } else if (taskResult.taskStatus === 'FAILED') {
        taskStatus.value = 'FAILED'
        const errorInfo = ERROR_CODE_MAP[taskResult.code]
        if (errorInfo) {
          failureReason.value = `${errorInfo.title}: ${errorInfo.description}。${errorInfo.suggestion}`
        } else {
          failureReason.value = taskResult.message || '任务执行失败'
        }
        message.error('扩图任务失败')
        clearPolling()
      }

      // 防止无限轮询（最多轮询20次，约1分钟）
      if (pollingCount >= 20) {
        taskStatus.value = 'FAILED'
        failureReason.value = '任务执行超时，请重试'
        message.error('任务执行超时')
        clearPolling()
      }

    } catch (error) {
      console.error('轮询任务状态失败', error)
      taskStatus.value = 'FAILED'
      failureReason.value = '检测任务状态失败: ' + error.message
      message.error('检测任务状态失败，请稍后重试')
      clearPolling()
    }
  }, 3000) // 每隔 3 秒轮询一次
}

// 重试任务
const retryTask = () => {
  resetState()
  createTask()
}

// 取消任务
const cancelTask = () => {
  clearPolling()
  taskStatus.value = ''
  taskId.value = ''
  progressPercent.value = 0
  message.info('已取消任务')
}

// 上传结果
const handleUpload = async () => {
  if (!resultImageUrl.value) {
    message.warning('没有可上传的结果图片')
    return
  }

  uploadLoading.value = true
  try {
    const params: API.PictureUploadRequest = {
      fileUrl: resultImageUrl.value,
      spaceId: props.spaceId,
    }
    if (props.picture) {
      params.id = props.picture.id
    }

    const res = await uploadPictureByUrlUsingPost(params)
    if (res.data.code === 0 && res.data.data) {
      message.success('图片上传成功')
      // 将上传成功的图片信息传递给父组件
      props.onSuccess?.(res.data.data)
      // 关闭弹窗
      closeModal()
    } else {
      throw new Error(res.data.message || '上传失败')
    }
  } catch (error) {
    message.error('图片上传失败: ' + error.message)
    console.error('Upload error:', error)
  } finally {
    uploadLoading.value = false
  }
}

// 清理定时器，避免内存泄漏
onUnmounted(() => {
  clearPolling()
})

// 暴露函数给父组件
defineExpose({
  openModal,
})
</script>

<style scoped>
.image-out-painting {
  text-align: center;
}

.image-container, .result-container {
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  padding: 12px;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.image-info {
  margin-top: 8px;
  text-align: center;
}

.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.loading-container p {
  margin: 0;
  color: #666;
}

.error-container {
  width: 100%;
}

.placeholder-container {
  color: #999;
}

.task-info {
  text-align: left;
}

:deep(.ant-progress-line) {
  width: 200px;
}

:deep(.ant-result) {
  padding: 24px 12px;
}

:deep(.ant-result-title) {
  font-size: 16px;
}

:deep(.ant-result-subtitle) {
  font-size: 12px;
}
</style>
